// #include "WS2812.h"
// #include "stm32f1xx_hal_tim.h"



// uint8_t WS2812_Buffer[WS2812_NUM * DATA_SIZE] = {0};
// TIM_HandleTypeDef htim2;
// DMA_HandleTypeDef hdma_tim2_ch3;
// /* 初始化WS2812
//  * 引脚：WS2812_GPIO_PORT->WS2812
//  */
// void WS2812_Init(void)
// {
	
// 	/* 初始化TIM2 */

// 	GPIO_InitTypeDef GPIO_InitStruct = {0};
// 	/* 初始化TIM2的通道3 */
// 	TIM_OC_InitTypeDef sConfigOC; 
// 	/* 初始化DMA */


// 	if (WS2812_GPIO_PORT == GPIOA)
// 		__HAL_RCC_GPIOA_CLK_ENABLE();
// 	else if (WS2812_GPIO_PORT == GPIOB)
// 		__HAL_RCC_GPIOB_CLK_ENABLE();
//     /* 使能复用时钟 */
//     __HAL_RCC_AFIO_CLK_ENABLE();
//     /* 使能TIM时钟 */
//     __HAL_RCC_TIM2_CLK_ENABLE();
//     /* 使能DMA时钟 */
//     __HAL_RCC_DMA1_CLK_ENABLE();

//     /* 初始化引脚 */

// 	GPIO_InitStruct.Pin = WS2812_PIN;
//     /* 复用推挽输出 */
// 	GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
// 	GPIO_InitStruct.Pull = GPIO_NOPULL;
// 	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
// 	HAL_GPIO_Init(WS2812_GPIO_PORT, &GPIO_InitStruct);

// 	htim2.Instance = TIM2;
// 	htim2.Init.Prescaler = 0; //不分频
// 	htim2.Init.CounterMode = TIM_COUNTERMODE_UP;    // 向上计数模式
// 	htim2.Init.Period = 90 - 1;   // 周期为90-1 即1.25us 
// 	htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;// 时钟分频因子为1
// 	HAL_TIM_PWM_Init(&htim2);


// 	sConfigOC.OCMode = TIM_OCMODE_PWM1;  // 选择PWM1模式
// 	sConfigOC.Pulse = 0;      // 初始占空比为0
// 	sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;  // 高电平有效
// 	sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;    // 互补通道高电平有效
// 	sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;    // 禁止快速模式
// 	sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;  // 空闲状态为低电平
// 	sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;    // 互补通道空闲状态为低电平
// 	HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3);    // 配置通道3

//     // 停止定时器
//     HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_3);

//     /* 配置DMA */
//     hdma_tim2_ch3.Instance = DMA1_Channel3; // 选择DMA1的通道3
//     hdma_tim2_ch3.Init.Direction = DMA_MEMORY_TO_PERIPH; // 内存到外设模式
//     hdma_tim2_ch3.Init.PeriphInc = DMA_PINC_DISABLE; // 外设地址不递增
//     hdma_tim2_ch3.Init.MemInc = DMA_MINC_ENABLE; // 内存地址递增
//     hdma_tim2_ch3.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; // 外设数据宽度为8位
//     hdma_tim2_ch3.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; // 内存数据宽度为8位
//     hdma_tim2_ch3.Init.Mode = DMA_CIRCULAR; // 循环模式
//     hdma_tim2_ch3.Init.Priority = DMA_PRIORITY_LOW; // 优先级为低
//     HAL_DMA_Init(&hdma_tim2_ch3);

//     /* 配置DMA */
//     __HAL_LINKDMA(&htim2, hdma[TIM_DMA_ID_CC3], hdma_tim2_ch3);

//     /* 启动TIM2的DMA */
// 	HAL_TIM_PWM_Start_DMA(&htim2, TIM_CHANNEL_3, (uint32_t *)WS2812_Buffer, WS2812_NUM);

// 	/* 关闭TIM2的中断 */
// 	HAL_TIM_PWM_Stop_DMA(&htim2, TIM_CHANNEL_3);// 关闭DMA传输

// }

// /* 复位灯带 */
// void WS2812_Reset(void)
// {
//     /* 关闭定时器 */
//     HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_3);
//     /* 设置占空比为0 */
//     __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, 0);
//     /* 等待一段时间 */
//     HAL_Delay(1);

// }

// /* 发送数据 */
// void PWM_WS2812B_Write_24Bits(uint16_t num,uint32_t GRB_Data)
// {
//   uint8_t i,j;
//   for(j = 0; j < num; j++)
//   {
//   	for(i = 0; i < DATA_SIZE; i++)
// 	{
// 		/*因为数据发送的顺序是GRB，高位先发，所以从高位开始判断，判断后比较值先放入缓存数组*/
// 		WS2812_Buffer[i] = ((GRB_Data << i) & 0x800000) ? T1H : T0H;
// 	}
//   }
// }

// // 点亮灯珠
// void PWM_WS2812B_Show(uint16_t num)
// {
//     // 设定DMA的数据计数器
//     //__HAL_DMA_SET_COUNTER(&hdma_tim2_ch3, num * DATA_SIZE);  // hdma_tim2_ch1 需要是TIM2的DMA句柄

//     // 启用DMA传输
//     HAL_DMA_Start(&hdma_tim2_ch3, (uint32_t)WS2812_Buffer, (uint32_t)&TIM2->CCR1, num * DATA_SIZE);  // sourceBuffer 是存放数据的缓冲区

//     // 启动定时器
//     HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3);  // htim2 是TIM2的句柄，确保你使用的是PWM模式

//     // 等待DMA传输完成
//     while (__HAL_DMA_GET_FLAG(&hdma_tim2_ch3, DMA_FLAG_TC3) == RESET);

//     // 停止DMA
//     HAL_DMA_Abort(&hdma_tim2_ch3);

//     // 清除DMA的标志位
//     __HAL_DMA_CLEAR_FLAG(&hdma_tim2_ch3, DMA_FLAG_TC3);

//     // 停止定时器
//     HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_3);
// }

// // 设置颜色函数（红、绿、蓝）
// void WS2812B_SetColor(uint8_t red, uint8_t green, uint8_t blue) {
//     // 设置每个 LED 的颜色
//     for (int i = 0; i < 8; i++) {
//         WS2812_Buffer[i] = (green & (1 << (7 - i))) ? 1 : 0;
//         WS2812_Buffer[8 + i] = (red & (1 << (7 - i))) ? 1 : 0;
//         WS2812_Buffer[16 + i] = (blue & (1 << (7 - i))) ? 1 : 0;
//     }
// }

#include "WS2812.h"
#include "stm32f1xx_hal.h"
#include "tim.h"
// WS2812 LED 数据传输的时序常量（以微秒为单位）
#define HIGH_TIME_1   0.8   // 逻辑 1 的高电平时间 (0.8 微秒)
#define LOW_TIME_1    0.45  // 逻辑 1 的低电平时间 (0.45 微秒)
#define HIGH_TIME_0   0.4   // 逻辑 0 的高电平时间 (0.4 微秒)
#define LOW_TIME_0    0.85  // 逻辑 0 的低电平时间 (0.85 微秒)

// 设置 GPIOB_Pin_10 引脚
#define LED_PIN GPIO_PIN_10
#define LED_PORT GPIOB



// 延时函数（使用定时器2产生微秒级延时）
void delay_us(uint16_t us) {
    __HAL_TIM_SET_COUNTER(&htim2, 0);  // 清除定时器计数器
    while (__HAL_TIM_GET_COUNTER(&htim2) < us);  // 等待计数器达到目标时间
}

// 初始化定时器2
void TIM2_Init(void) {
  /* USER CODE BEGIN TIM2_Init 0 */

  /* USER CODE END TIM2_Init 0 */

    //定时器时钟初始化
    // 定时器2的句柄
    TIM_HandleTypeDef htim2;
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};

  /* USER CODE BEGIN TIM2_Init 1 */

  /* USER CODE END TIM2_Init 1 */
  htim2.Instance = TIM2; // 选择 TIM2
  htim2.Init.Prescaler = 0; // 不分频 
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP; // 向上计数模式
  htim2.Init.Period = 89;   // 周期为90-1 即1.25us
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; // 时钟分频因子为1
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; // 禁止自动重装载预加载
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; // 内部时钟源
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; // 主输出触发源
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; // 主从模式禁用
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1; // PWM1模式
  sConfigOC.Pulse = 0; // 初始占空比为0
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; // 高电平有效
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; // 禁止快速模式
  if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM2_Init 2 */

  /* USER CODE END TIM2_Init 2 */
  HAL_TIM_MspPostInit(&htim2); // 调用 HAL_TIM_MspPostInit 函数

}

// 初始化 GPIOB_Pin_10 引脚
void WS2812_Init(void) {
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    __HAL_RCC_GPIOB_CLK_ENABLE();  // 使能 GPIOB 时钟
    //使能复用推挽时钟
    __HAL_RCC_AFIO_CLK_ENABLE();

    GPIO_InitStruct.Pin = LED_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;  // 复用推挽输出模式
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

    HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct);

    // 重映射 TIM2 的部分通道到 GPIOB_Pin_10
    __HAL_AFIO_REMAP_TIM2_PARTIAL_2();


    TIM2_Init();  // 初始化定时器2

}

uint16_t send_Buf[NUM];

//#define PROCESS_DELAY 5
//#define SECTION_DELAY 100

void WS_Load(void) { HAL_TIM_PWM_Start_DMA(&htim2, TIM_CHANNEL_3, (uint32_t*)send_Buf, NUM); }
void WS_CloseAll(void)
{
	uint16_t i;
	for (i = 0; i < PIXEL_NUM * 24; i++)
		send_Buf[i] = WS0;    // 写入逻辑0的占空比
	for (i = PIXEL_NUM * 24; i < NUM; i++)
		send_Buf[i] = 0;    // 占空比比为0，全为低电平
	WS_Load();
}

void WS_WriteAll_RGB(uint8_t n_R, uint8_t n_G, uint8_t n_B)
{
	uint16_t i, j;
	uint8_t dat[24];
	// 将RGB数据进行转换
	for (i = 0; i < 8; i++)
	{
		dat[i] = ((n_G & 0x80) ? WS1 : WS0);
		n_G <<= 1;
	}
	for (i = 0; i < 8; i++)
	{
		dat[i + 8] = ((n_R & 0x80) ? WS1 : WS0);
		n_R <<= 1;
	}
	for (i = 0; i < 8; i++)
	{
		dat[i + 16] = ((n_B & 0x80) ? WS1 : WS0);
		n_B <<= 1;
	}
	for (i = 0; i < PIXEL_NUM; i++)
	{
		for (j = 0; j < 24; j++)
		{
			send_Buf[i * 24 + j] = dat[j];
		}
	}
	for (i = PIXEL_NUM * 24; i < NUM; i++)
		send_Buf[i] = 0;    // 占空比比为0，全为低电平
	WS_Load();
}

uint32_t WS281x_Color(uint8_t red, uint8_t green, uint8_t blue) { return green << 16 | red << 8 | blue; }

void WS281x_SetPixelColor(uint16_t n, uint32_t GRBColor)
{
	uint8_t i;
	if (n < PIXEL_NUM)
	{
		for (i = 0; i < 24; ++i)
			send_Buf[24 * n + i] = (((GRBColor << i) & 0X800000) ? WS1 : WS0);
	}
}

void WS281x_SetPixelRGB(uint16_t n, uint8_t red, uint8_t green, uint8_t blue)
{
	uint8_t i;

	if (n < PIXEL_NUM)
	{
		for (i = 0; i < 24; ++i)
			send_Buf[24 * n + i] = (((WS281x_Color(red, green, blue) << i) & 0X800000) ? WS1 : WS0);
	}
}

uint32_t Wheel(uint8_t WheelPos)
{
	WheelPos = 255 - WheelPos;
	if (WheelPos < 85)
	{
		return WS281x_Color(255 - WheelPos * 3, 0, WheelPos * 3);
	}
	if (WheelPos < 170)
	{
		WheelPos -= 85;
		return WS281x_Color(0, WheelPos * 3, 255 - WheelPos * 3);
	}
	WheelPos -= 170;
	return WS281x_Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

void rainbow(uint8_t wait)
{
	uint32_t timestamp = HAL_GetTick();
	uint16_t i;
	static uint8_t j;
	static uint32_t next_time = 0;

	uint32_t flag = 0;
	if (next_time < wait)
	{
		if ((uint64_t)timestamp + wait - next_time > 0)
			flag = 1;
	}
	else if (timestamp > next_time)
	{
		flag = 1;
	}
	if (flag)    // && (timestamp - next_time < wait*5))
	{
		j++;
		next_time = timestamp + wait;
		for (i = 0; i < PIXEL_NUM; i++)
		{
			WS281x_SetPixelColor(i, Wheel((i + j) & 255));
		}
	}
	WS_Load();
}

void rainbowCycle(uint8_t wait)
{
	uint32_t timestamp = HAL_GetTick();
	uint16_t i;
	static uint8_t j;
	static uint32_t next_time = 0;

	static uint8_t loop = 0;
	if (loop == 0)
		next_time = timestamp;
	loop = 1;    //首次调用初始化

	if ((timestamp > next_time))    // && (timestamp - next_time < wait*5))
	{
		j++;
		next_time = timestamp + wait;
		for (i = 0; i < PIXEL_NUM; i++)
		{
			WS281x_SetPixelColor(i, Wheel(((i * 256 / (PIXEL_NUM)) + j) & 255));
		}
	}
	WS_Load();
	
}
